package tianhao.luo.stack;

/**
 * 单链表栈
 * <p>
 * 无限大
 *
 * @author: tianhao.luo@hand-china.com 2021/6/15  16:25
 */
public class SingleLinkedStack<T> {

    /**
     * 栈顶指针
     */
    private LinkedStackEle<T> top = null;
    /**
     * 栈底指针
     */
    private LinkedStackEle<T> end = null;

    /**
     * 入栈
     * 链表栈,无限大,可以一直加入
     *
     * @param ele 元素
     */
    public void push(T ele) {
        LinkedStackEle<T> tLinkedStackEle = new LinkedStackEle<>(ele);
        // 将栈顶指针对应得元素得next指向加入得元素
        if (top == null) {
            top = tLinkedStackEle;
            end = tLinkedStackEle;
        } else {
            top.next = tLinkedStackEle;
            top = tLinkedStackEle;
        }

    }

    /**
     * 是否空链表
     */
    public boolean isEmpty() {
        return top == null;
    }

    /**
     * 弹出栈顶元素
     *
     * @return 栈顶内容
     */
    public T pop() {
        T ele = top.getEle();

        LinkedStackEle<T> temp = end;
        while (true) {
            // 从栈底找到栈顶
            if (temp.next == top) {
                break;
            }
            temp = temp.next;
        }
        top = temp;
        return ele;
    }

    /**
     * 展示栈顶元素
     *
     * @return 内容
     */
    public T peek() {
        return top.getEle();
    }

    /**
     * 反转链表
     */
    public void reverseList() {
        SingleLinkedStack<T> tempStack = new SingleLinkedStack<>();
        // 新栈
        tempStack.end = top;
        tempStack.top = end;

                // 从旧栈顶取出元素,加入到tempStack中

        LinkedStackEle<T> temp = end;

        while (true) {
            // 从栈底找到栈顶
            if (temp == top) {
                break;
            }
            // 将temp放入新栈中,并且每次都是放入新栈的end节点的next
            LinkedStackEle<T> tempEndNext = tempStack.end.next;
            tempStack.end.next = temp;
            LinkedStackEle<T> tempNext = temp.next;
            temp.next = tempEndNext;
            temp = tempNext;
        }

        LinkedStackEle<T> tempEnd = tempStack.end;
        while (true){
            if (tempEnd == tempStack.top){
                // 到栈最后一个元素了
                break;
            }
            tempEnd = tempEnd.next;
        }

        top = tempStack.top;
        end = tempStack.end;

    }


    /**
     * 展示链表中所有元素
     */
    public void list(){
        LinkedStackEle<T> tempEnd = end;
        while (true){
            System.out.println("元素为:"+tempEnd.getEle().toString());
            if (tempEnd == top){
                break;
            }
            tempEnd = tempEnd.next;
        }

    }


    /**
     * 链表栈长度
     *
     * @return 长度
     */
    public Integer getSize() {
        LinkedStackEle<T> temp = end;
        int length = 0;
        while (true) {
            // 从栈底找到栈顶
            if (temp == top) {
                length++;
                break;
            }
            temp = temp.next;
            length++;
        }
        return length;
    }
}
